using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Xml;
using System.Globalization;
using System.Collections.Generic;

namespace Thinktecture.Tools.Web.Services.CodeGeneration
{
	/// <summary>
	/// Summary description for ConfigWriter.
	/// </summary>
	internal class ConfigHelper
	{
		private ConfigHelper() {}

		internal static string GetLastServiceEndpointName(string configFile)
		{
			string result = "WebService.EndpointUrl.";
			int highestNumber = 0;

			if (File.Exists(configFile))
			{	
				ConfigReader configReader = new ConfigReader(configFile);
				ArrayList settingsKeys = new ArrayList(configReader.GetEntryNames("appSettings"));
				
				if(settingsKeys.Count > 0)
				{
					foreach(string keyName in settingsKeys)
					{
						if(keyName.IndexOf("WebService.EndpointUrl.") > -1)
						{
							int index = keyName.LastIndexOf(".");
							string number = keyName.Substring(index + 1, keyName.Length - index - 1);
							if(Convert.ToInt32(number) + 1 > highestNumber) highestNumber = Convert.ToInt32(number) + 1;
						}
					}
				
				}
				
				result += highestNumber.ToString();
				Console.WriteLine(highestNumber);
			}
			else
				result += 0.ToString();

			return result;
		}

		internal static void SetAppSettingsValue(string configFile, string key, string theValue)
		{
			if (!File.Exists(configFile))
			{				
				XmlTextWriter writer = new XmlTextWriter(configFile, Encoding.UTF8);			
				writer.Formatting = Formatting.Indented;
	            
				writer.WriteStartDocument();
				
				writer.WriteStartElement("configuration");			
				writer.WriteStartElement("appSettings");
				writer.WriteStartElement("add");
				writer.WriteAttributeString("key", null, key);				
				writer.WriteAttributeString("value", null, theValue);
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
			
				writer.Close();
   			}

			XmlDocument doc = new XmlDocument();
			doc.Load(configFile);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);

			XmlElement root = doc.DocumentElement;
			
			XmlAttribute attribute = null;
			XmlNode sectionNode = null;

			sectionNode = root.SelectSingleNode("tns:appSettings", nsmgr);
			if (sectionNode == null)
				sectionNode = root.AppendChild(doc.CreateElement("appSettings"));

			XmlNode entryNode = sectionNode.SelectSingleNode("tns:add[@key=\"" + key + "\"]", nsmgr);
			if (entryNode == null)
			{
				XmlElement element = doc.CreateElement("add");
				attribute = doc.CreateAttribute("key");
				attribute.Value = key;
				element.Attributes.Append(attribute);			

				entryNode = sectionNode.AppendChild(element);			
			}

			attribute = doc.CreateAttribute("value");
			attribute.Value = theValue;
			entryNode.Attributes.Append(attribute);			

			doc.Save(configFile);
		}

		internal static void SetWebServicesPipelineConfig(string configFile, string type)
		{
			if (!File.Exists(configFile))
			{	
				XmlTextWriter writer = new XmlTextWriter(configFile, Encoding.UTF8);			
				writer.Formatting = Formatting.Indented;
	            
				writer.WriteStartDocument();

				writer.WriteStartElement("configuration");			
				writer.WriteStartElement("system.web");
				writer.WriteStartElement("webServices");
				writer.WriteStartElement("soapExtensionTypes");
				writer.WriteStartElement("add");
				writer.WriteAttributeString("type", null, type);				
				writer.WriteAttributeString("priority", null, "1");
				writer.WriteAttributeString("group", null, "0");
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				
				writer.Close();
   				
				return;
			}

			XmlDocument doc = new XmlDocument();
			doc.Load(configFile);
			XmlElement root = doc.DocumentElement;
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);

			XmlAttribute attribute = null;
			XmlNode sectionNode = null;
			XmlNode webSectionNode = null;            

			webSectionNode = root.SelectSingleNode("tns:system.web", nsmgr);

            if (webSectionNode == null)
            {
                webSectionNode = root.AppendChild(doc.CreateElement("system.web"));
                webSectionNode = webSectionNode.AppendChild(doc.CreateElement("webServices"));
            }
            else
            {
                XmlNode webServicesNode = webSectionNode.SelectSingleNode("tns:webServices", nsmgr);

                if (webServicesNode == null)
                {
                    webSectionNode = webSectionNode.AppendChild(doc.CreateElement("webServices"));
                }
                else
                {
                    webSectionNode = webServicesNode;
                }
            }

			sectionNode = webSectionNode.SelectSingleNode("tns:soapExtensionTypes", nsmgr);
			if (sectionNode == null)
			{
				sectionNode = webSectionNode.AppendChild(doc.CreateElement("soapExtensionTypes"));
			}

			XmlNode entryNode = sectionNode.SelectSingleNode("tns:add[@type=\"" + type + "\"]", nsmgr);
			if (entryNode == null)
			{
				XmlElement element = doc.CreateElement("add");
				attribute = doc.CreateAttribute("type");
				attribute.Value = type;
				element.Attributes.Append(attribute);

				attribute = doc.CreateAttribute("priority");
				attribute.Value = "1";
				element.Attributes.Append(attribute);

				attribute = doc.CreateAttribute("group");
				attribute.Value = "0";
				element.Attributes.Append(attribute);

				entryNode = sectionNode.AppendChild(element);			
			}		

			doc.Save(configFile);
		}

		internal static void DisableWsdlConfig(string configFile)
		{
			if (!File.Exists(configFile))
			{	
				XmlTextWriter writer = new XmlTextWriter(configFile, Encoding.UTF8);			
				writer.Formatting = Formatting.Indented;
	            
				writer.WriteStartDocument();

				writer.WriteStartElement("configuration");			
				writer.WriteStartElement("system.web");
				writer.WriteStartElement("webServices");
				writer.WriteStartElement("protocols");
				writer.WriteStartElement("remove");
				writer.WriteAttributeString("name", null, "Documentation");				
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				
				writer.Close();
   				
				return;
			}

			XmlDocument doc = new XmlDocument();
			doc.Load(configFile);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);

            XmlElement root = doc.DocumentElement;
			
			XmlAttribute attribute = null;
			XmlNode sectionNode = null;

			sectionNode = root.SelectSingleNode("tns:system.web/tns:webServices/tns:protocols", nsmgr);
			if (sectionNode == null)
			{
				sectionNode = root.SelectSingleNode("tns:system.web/tns:webServices", nsmgr);
				if (sectionNode == null)
				{
					sectionNode = root.SelectSingleNode("tns:system.web", nsmgr);
					if (sectionNode == null)
					{
						sectionNode = root.AppendChild(doc.CreateElement("system.web"));
						sectionNode = sectionNode.AppendChild(doc.CreateElement("webServices"));
						sectionNode = sectionNode.AppendChild(doc.CreateElement("protocols"));
					}
					else
					{
						sectionNode = sectionNode.AppendChild(doc.CreateElement("webServices"));
						sectionNode = sectionNode.AppendChild(doc.CreateElement("protocols"));
					}
				}
				else
				{
					sectionNode = sectionNode.AppendChild(doc.CreateElement("protocols"));
				}
				
			}

			XmlNode entryNode = sectionNode.SelectSingleNode("tns:remove[@name=\"Documentation\"]", nsmgr);
			if (entryNode == null)
			{
				XmlElement element = doc.CreateElement("remove");
				attribute = doc.CreateAttribute("name");
				attribute.Value = "Documentation";
				element.Attributes.Append(attribute);

				entryNode = sectionNode.AppendChild(element);			
			}		

			doc.Save(configFile);
		}

		/// <summary>
		/// This method adds the necessary elements to the configuration file in order to 
		/// add a new HttpModule to the ASP.Net Http request processing pipe line. 
		/// </summary>
		/// <param name="configFile">Name of the configuration file.</param>
		/// <param name="moduleNamespace">Namespace of the Http Module.</param>
		/// <param name="moduleName">Class name of the Http Module.</param>
		/// <author>BDS - thinktecture</author>
		internal static void AttachHttpModule(string configFile, string moduleNamespace,
			string moduleName, string assemblyName)
		{
			// BDS: Fixed a bug here. If we had a blank namespace name; we ended up with a fully qulified 
			// type name which started with a period.
			string type = "";
            
            if (moduleNamespace.Trim() == "")
            {
                type = moduleName;
            }
            else
            {
                type = string.Format(CultureInfo.CurrentCulture, "{0}.{1}", moduleNamespace, moduleName);
            }

            if (assemblyName != null && assemblyName.Trim() != "")
            {
                type = string.Format(CultureInfo.CurrentCulture, "{0}, {1}", type, assemblyName);
            }

			// Create the file if it does not exists.
			if (!File.Exists(configFile))
			{	
				XmlTextWriter writer = new XmlTextWriter(configFile, Encoding.UTF8);			
				writer.Formatting = Formatting.Indented;
	            
				writer.WriteStartDocument();

				writer.WriteStartElement("configuration");			
				writer.WriteStartElement("system.web");
				writer.WriteStartElement("httpModules");
				writer.WriteStartElement("add");
				writer.WriteAttributeString("type", null, type);				
				writer.WriteAttributeString("name", null, moduleName);
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				
				writer.Close();
   				
				return;
			}

			// Load the XML.
			XmlDocument doc = new XmlDocument();
			doc.Load(configFile);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);
			XmlElement root = doc.DocumentElement;
			
			XmlAttribute attribute = null;
			XmlNode sectionNode = null;

			// Look for the httpModules element and create one if it does not exists.
			sectionNode = root.SelectSingleNode("tns:system.web/tns:httpModules", nsmgr);
			if (sectionNode == null)
			{
				sectionNode = root.SelectSingleNode("tns:system.web", nsmgr);
				if (sectionNode == null)
				{
					sectionNode = root.AppendChild(doc.CreateElement("system.web"));
					sectionNode = sectionNode.AppendChild(doc.CreateElement("httpModules"));
				}
				else
				{
					sectionNode = sectionNode.AppendChild(doc.CreateElement("httpModules"));
				}
			}
			
			// Add a child element to the httpModules element.
			XmlNode entryNode = sectionNode.SelectSingleNode("tns:add[@name=\"" + moduleName + "\"]", nsmgr);
			if(entryNode == null)
			{
				XmlElement element = doc.CreateElement("add");

				// Add the two attributes. (type and name).
				attribute = doc.CreateAttribute("type");
				attribute.Value = type;
				element.Attributes.Append(attribute);
			
				attribute = doc.CreateAttribute("name");
				attribute.Value = moduleName;
				element.Attributes.Append(attribute);
			
				sectionNode.AppendChild(element);			
			}
			else
			{
				// BDS: Fixed a bug here. We did not check whether we have the "type" attribute in handy, 
				// before setting its value.
				if(entryNode.Attributes["type"] == null)
				{
					entryNode.Attributes.Append(doc.CreateAttribute("type"));
				}
				entryNode.Attributes["type"].Value = type;				
			}

			// Finally save the XML file.
			doc.Save(configFile);
		}

		/// <summary>
		/// This method adds the necessary elements to the configuration file in order to 
		/// add a new HttpHandler to the ASP.Net Http request processing pipe line. 
		/// </summary>
		/// <param name="configFile">Name of the configuration file.</param>
		/// <param name="path">Path for the extensions handled by the new handler.</param>
		/// <param name="type">Type of the new new handler.</param>
		/// <author>BDS - thinktecture</author>
		internal static void AttachHttpHandler(string configFile, string path,
			string type)
		{
			// Create the file if it does not exists.
			if (!File.Exists(configFile))
			{	
				XmlTextWriter writer = new XmlTextWriter(configFile, Encoding.UTF8);			
				writer.Formatting = Formatting.Indented;
	            
				writer.WriteStartDocument();

				writer.WriteStartElement("configuration");			
				writer.WriteStartElement("system.web");
				writer.WriteStartElement("httpHandlers");
				writer.WriteStartElement("add");
				writer.WriteAttributeString("verb", null, "*");				
				writer.WriteAttributeString("path", null, path);
				writer.WriteAttributeString("type", null, type);
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				
				writer.Close();
   				
				return;
			}

			// Load the XML.
			XmlDocument doc = new XmlDocument();
			doc.Load(configFile);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);
			XmlElement root = doc.DocumentElement;
			
			XmlAttribute attribute = null;
			XmlNode sectionNode = null;

			// Look for the httpHandlers element and create one if it does not exists.
			sectionNode = root.SelectSingleNode("tns:system.web/tns:httpHandlers", nsmgr);
			if (sectionNode == null)
			{
				sectionNode = root.SelectSingleNode("tns:system.web", nsmgr);
				if (sectionNode == null)
				{
					sectionNode = root.AppendChild(doc.CreateElement("system.web"));
					sectionNode = sectionNode.AppendChild(doc.CreateElement("httpHandlers"));
				}
				else
				{
					sectionNode = sectionNode.AppendChild(doc.CreateElement("httpHandlers"));
				}
			}
			
			// Add a child element to the httpModules element.
			XmlNode entryNode = sectionNode.SelectSingleNode("tns:add[@path=\"" + path + "\"]", nsmgr);
			if(entryNode == null)
			{
				XmlElement element = doc.CreateElement("add");

				// Add the two attributes. (type and name).
				attribute = doc.CreateAttribute("verb");
				attribute.Value = "*";
				element.Attributes.Append(attribute);
			
				attribute = doc.CreateAttribute("path");
				attribute.Value = path;
				element.Attributes.Append(attribute);

				attribute = doc.CreateAttribute("type");
				attribute.Value = type;
				element.Attributes.Append(attribute);
			
				sectionNode.AppendChild(element);			
			}
			else
			{
				entryNode.Attributes["type"].Value = type;				
			}
			// Finally save the XML file.
			doc.Save(configFile);
		}

		/// <summary>
		/// This method adds the necessary elements to the configuration file in order to 
		/// configure the asmx documentation page
		/// </summary>
		/// <param name="configFile">Full file name of the configuration file.</param>
		/// <param name="helpGenerator">File name of the help generator.</param>
		/// <author>BDS - thinktecture.</author>
		internal static void SetAsmxHelpFileGenerator(string configFile, string helpGenerator)
		{
			if (!File.Exists(configFile))
			{	
				XmlTextWriter writer = new XmlTextWriter(configFile, Encoding.UTF8);			
				writer.Formatting = Formatting.Indented;
	            
				writer.WriteStartDocument();

				writer.WriteStartElement("configuration");			
				writer.WriteStartElement("system.web");
				writer.WriteStartElement("webServices");
				writer.WriteStartElement("wsdlHelpGenerator");
				writer.WriteAttributeString("href", null, helpGenerator);				
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				writer.WriteEndElement();
				
				writer.Close();
   				
				return;
			}

			XmlDocument doc = new XmlDocument();
			doc.Load(configFile);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);
			XmlElement root = doc.DocumentElement;
			
			XmlAttribute attribute = null;
			XmlNode sectionNode = null;

			sectionNode = root.SelectSingleNode("tns:system.web/tns:webServices", nsmgr);
			if (sectionNode == null)
			{
				sectionNode = root.SelectSingleNode("tns:system.web", nsmgr);
				if (sectionNode == null)
				{
					sectionNode = root.AppendChild(doc.CreateElement("system.web"));
					sectionNode = sectionNode.AppendChild(doc.CreateElement("webServices"));
				}
				else
				{
					sectionNode = sectionNode.AppendChild(doc.CreateElement("webServices"));
				}
			}
				
			XmlNode entryNode = sectionNode.SelectSingleNode("tns:wsdlHelpGenerator", nsmgr);
			if (entryNode == null)
			{
				XmlElement element = doc.CreateElement("wsdlHelpGenerator");
				attribute = doc.CreateAttribute("href");
				attribute.Value = helpGenerator;
				element.Attributes.Append(attribute);
				entryNode = sectionNode.AppendChild(element);			
			}		
			else
			{
				foreach(XmlAttribute attrib in entryNode.Attributes)
				{
					if(attrib.Name.ToLower() == "href")
					{
						attrib.Value = helpGenerator;
						break;
					}
				}
			}

			doc.Save(configFile);
		}
		
		
		/// <summary>
		/// This method removes a specified application setting value from a specified configuration file.
		/// </summary>
		/// <param name="configFile">Path of the configuration file.</param>
		/// <param name="key">Key of the application setting to remove.</param>
		/// <remarks>This method is not yet called from anyone.</remarks>
		/// <author>Buddhike de Silva</author>
		internal static void RemoveAppSettingsValue(string configFile, string key)
		{
			if(File.Exists(configFile))
			{
				XmlDocument doc = new XmlDocument();
				doc.Load(configFile);
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);
				XmlElement root = doc.DocumentElement;
				XmlNode sectionNode = root.SelectSingleNode("tns:appSettings", nsmgr);
				XmlNode entryNode = sectionNode.SelectSingleNode("tns:add[@key=\"" + key + "\"]", nsmgr);
				if(entryNode != null)
				{
					sectionNode.RemoveChild(entryNode);
					doc.Save(configFile);
				}
			}
		}

        internal static void AddDisableWsdl(string configFile, string asmxFileName)
        {            
            // Create the file if it does not exists.
            if (!File.Exists(configFile))
            {
                XmlTextWriter writer = new XmlTextWriter(configFile, Encoding.UTF8);
                writer.Formatting = Formatting.Indented;

                writer.WriteStartDocument();

                writer.WriteStartElement("configuration");
                writer.WriteStartElement("appSettings");
                writer.WriteStartElement("add");                
                writer.WriteAttributeString("name", null, "disableWsdl");
                writer.WriteAttributeString("value", null, asmxFileName);
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();                
                writer.Close();
                return;
            }

            // Load the XML.
            XmlDocument doc = new XmlDocument();
            doc.Load(configFile);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);       
            XmlNode settingNode = null;
            settingNode = doc.SelectSingleNode("/tns:configuration/tns:appSettings/tns:add[@key=\"disableWsdl\"]", nsmgr);

            if (settingNode == null)
            {
                settingNode = doc.SelectSingleNode("/tns:configuration", nsmgr);

                if (settingNode == null)
                {                    
                    settingNode = (XmlNode)doc.CreateElement("configuration");
                    settingNode = settingNode.AppendChild(
                        doc.CreateElement("appSettings"));
                    settingNode = settingNode.AppendChild(
                        doc.CreateElement("add"));                    
                }
                else
                {
                    XmlNode childNode = settingNode.SelectSingleNode("tns:appSettings", nsmgr);

                    if (childNode == null)
                    {
                        settingNode = settingNode.AppendChild(
                        doc.CreateElement("appSettings"));

                        settingNode = settingNode.AppendChild(
                            doc.CreateElement("add"));
                    }
                    else
                    {
                        settingNode = childNode;
                        childNode = childNode.SelectSingleNode("tns:add[@key=\"disableWsdl\"]", nsmgr);
                        
                        if (childNode == null)
                        {
                            settingNode = settingNode.AppendChild(
                            doc.CreateElement("add"));
                        }
                    }
                }
            }

            XmlAttribute value = settingNode.Attributes["value"];
            if (value == null)
            {
                XmlAttribute key = doc.CreateAttribute("key");                
                key.Value = "disableWsdl";
                settingNode.Attributes.Append(key);

                value = doc.CreateAttribute("value");                
                value.Value = asmxFileName;
                settingNode.Attributes.Append(value);
            }
            else
            {
                if (value.Value != "")
                {
                    string[] asmxFileNames = value.Value.Split(new string[] { ";" },
                        StringSplitOptions.RemoveEmptyEntries);

                    bool found = false;
                    foreach (string fn in asmxFileNames)
                    {
                        if (fn == asmxFileName)
                        {
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        value.Value = value.Value + ";" + asmxFileName;
                    }
                }
                else
                {
                    value.Value = asmxFileName;
                }
            }

            // Finally save the XML file.
            doc.Save(configFile);            
        }

        internal static void RemoveDisableWsdl(string configFile, string asmxFileName)
        {
            if (File.Exists(configFile))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(configFile);
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);
                XmlNode settingNode = null;
                settingNode = doc.SelectSingleNode("/tns:configuration/tns:appSettings/tns:add[@key=\"disableWsdl\"]", nsmgr);

                if (settingNode != null)
                {
                    XmlAttribute value = settingNode.Attributes["value"];                    
                    if(value != null)
                    {
                        string[] asmxFileNames = value.Value.Split(new string[] { ";" }, 
                            StringSplitOptions.RemoveEmptyEntries);

                        List<string> newAsmxFileNames = new List<string>();

                        foreach (string fn in asmxFileNames)
                        {
                            if (fn != asmxFileName)
                            {
                                newAsmxFileNames.Add(fn);
                            }
                        }

                        value.Value = string.Join(";", newAsmxFileNames.ToArray());
                        value.Value = value.Value.TrimEnd(';');

                        doc.Save(configFile);
                    }
                }                
            }
        }

        /// <summary>
        /// Adds the neccessary elements to disable SOAP 1.2 protocol.
        /// </summary>        
        internal static void DisableSoap12(string configFile)
        {
            // Create the file if it does not exists.
            if (!File.Exists(configFile))
            {
                XmlTextWriter writer = new XmlTextWriter(configFile, Encoding.UTF8);
                writer.Formatting = Formatting.Indented;

                writer.WriteStartDocument();

                writer.WriteStartElement("configuration");
                writer.WriteStartElement("system.web");
                writer.WriteStartElement("webServices");
                writer.WriteStartElement("protocols");
                writer.WriteStartElement("remove");

                writer.WriteAttributeString("name", null, "HttpSoap12");

                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.WriteEndElement();
                writer.Close();
                return;
            }
            
            // Load the XML.
            XmlDocument doc = new XmlDocument();
            doc.Load(configFile);            
            XmlNode settingNode = null;
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);
            settingNode = doc.SelectSingleNode("/tns:configuration/tns:system.web/tns:webServices/tns:protocols/tns:remove[@name=\"HttpSoap12\"]", nsmgr);

            if (settingNode == null)
            {                
                settingNode = doc.SelectSingleNode("/tns:configuration", nsmgr);

                if (settingNode == null)
                {                    
                    settingNode = (XmlNode)doc.CreateElement("configuration");
                    settingNode = doc.AppendChild(settingNode);
                    settingNode = settingNode.AppendChild(doc.CreateElement("system.web"));
                    settingNode = settingNode.AppendChild(doc.CreateElement("webServices"));
                    settingNode = settingNode.AppendChild(doc.CreateElement("protocols"));
                    settingNode = settingNode.AppendChild(doc.CreateElement("remove"));
                }
                else
                {
                    XmlNode childNode = settingNode.SelectSingleNode("tns:system.web", nsmgr);

                    if (childNode == null)
                    {
                        settingNode = settingNode.AppendChild(doc.CreateElement("system.web", doc.DocumentElement.NamespaceURI));
                        settingNode = settingNode.AppendChild(doc.CreateElement("webServices"));
                        settingNode = settingNode.AppendChild(doc.CreateElement("protocols"));
                        settingNode = settingNode.AppendChild(doc.CreateElement("remove"));
                    }
                    else
                    {
                        settingNode = childNode;
                        childNode = childNode.SelectSingleNode("tns:webServices", nsmgr);

                        if (childNode == null)
                        {
                            settingNode = settingNode.AppendChild(doc.CreateElement("webServices"));
                            settingNode = settingNode.AppendChild(doc.CreateElement("protocols"));
                            settingNode = settingNode.AppendChild(doc.CreateElement("remove"));
                        }
                        else
                        {
                            settingNode = childNode;
                            childNode = childNode.SelectSingleNode("tns:protocols", nsmgr);

                            if (childNode == null)
                            {
                                settingNode = settingNode.AppendChild(doc.CreateElement("protocols"));
                                settingNode = settingNode.AppendChild(doc.CreateElement("remove"));
                            }
                            else
                            {
                                settingNode = childNode;
                                childNode = childNode.SelectSingleNode("tns:remove", nsmgr);

                                if (childNode == null)
                                {
                                    settingNode = settingNode.AppendChild(doc.CreateElement("remove"));
                                }
                                else
                                {
                                    settingNode = childNode;
                                }
                            }
                        }
                    }
                }
            }

            XmlAttribute name = settingNode.Attributes["name"];
            if (name == null)
            {
                XmlAttribute newName = doc.CreateAttribute("name");
                newName.Value = "HttpSoap12";
                settingNode.Attributes.Append(newName);
            }

            // Finally save the XML file.
            doc.Save(configFile);
        }

        /// <summary>
        /// Removes the appropriate elements which disable the SOAP 1.2 protocol.
        /// </summary>        
        internal static void EnableSoap12(string configFile)
        {
            // Load the XML.
            XmlDocument doc = new XmlDocument();
            doc.Load(configFile);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);
            XmlNode settingNode = null;

            // Check for the Soap12 protocol block element and remove if neccessary.
            settingNode = doc.SelectSingleNode("/tns:configuration/tns:system.web/tns:webServices/tns:protocols/tns:remove[@name=\"HttpSoap12\"]", nsmgr);

            if (settingNode != null)
            {
                settingNode.ParentNode.RemoveChild(settingNode);                
                doc.Save(configFile);
            }
        }
	}

	internal class ConfigReader
	{
		private string fileName = "";

		public ConfigReader(string configFileName)
		{
			fileName = configFileName;
		}

		private XmlDocument GetXmlDocument()
		{
			if (!File.Exists(fileName))
				return null;

			XmlDocument doc = new XmlDocument();
			doc.Load(fileName);
					
			return doc;
		}

		public object GetValue(string section, string entry)
		{
			try
			{
				XmlDocument doc = GetXmlDocument();
				XmlElement root = doc.DocumentElement;
                XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
                nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);

				XmlNode entryNode = root.SelectSingleNode("tns:" + section + "/tns:add[@key=\"" + entry + "\"]", nsmgr);
				return entryNode.Attributes["value"].Value;
			}
			catch
			{				
				return null;
			}
		}

		public string[] GetEntryNames(string section)
		{
			XmlDocument doc = GetXmlDocument();
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("tns", doc.DocumentElement.NamespaceURI);
			XmlElement root = doc.DocumentElement;
		    
			XmlNodeList entryNodes = root.SelectNodes("tns:" + section + "/tns:add[@key]", nsmgr);
			if (entryNodes == null)
				return null;

			string[] entries = new string[entryNodes.Count];
			int i = 0;
		
			foreach (XmlNode node in entryNodes)
				entries[i++] = node.Attributes["key"].Value;
		
			return entries;
		}        
	}
}
